package controllers;

import java.util.ArrayList;
import java.util.Calendar;

import models.ApiKey;
import models.User;

import org.apache.commons.lang.RandomStringUtils;
import org.codehaus.jackson.node.ObjectNode;

import other.Utils;
import play.data.Form;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Security;

@Security.Authenticated(Secure.class)
public class Users extends Controller {

    static Form<User> userForm;

    public static Result index() {
        return ok(views.html.User.User.index.render());
    }

    public static Result listUsers() {
        return ok(views.html.User.User.listUsers
                .render(User.find.all(), session().get("keyId"), session().get("vCode")));
    }

    public static Result addUserForm(long id) {
        userForm = Form.form(User.class);
        // Fill form with values
        if (id > 0) {
            userForm = userForm.fill(User.find.byId(id));
        }
        return ok(views.html.User.User.addUser.render(userForm, Boolean.valueOf(session().get("isAdmin")),
                id > 0 ? userForm.get().isAdmin() : false, ""));
    }

    public static Result addUser() {
        Form<User> filledUserForm = userForm.bindFromRequest();
        User user = (!filledUserForm.field("id").value().isEmpty()) ? User.find.byId(Long.valueOf(filledUserForm.field(
                "id").value())) : new User();

        if (user.getId() != null) {
            filledUserForm.errors().remove("password");
        }

        if (filledUserForm.hasErrors()) {
            // Return error if empty fields
            return ok(views.html.User.User.addUser.render(filledUserForm, Boolean.valueOf(session().get("isAdmin")),
                    false, ""));
        } else {
            ObjectNode result = Json.newObject();
            result.put("redirect", true);
            user.setUsername(filledUserForm.field("username").value());
            if (filledUserForm.field("password").value() != null) {
                user.setPassword(Utils.getSaltedPassword(filledUserForm.field("password").value()));
            }
            user.setAdmin(filledUserForm.field("isAdmin").value() != null);
            ApiKey apiKey = new ApiKey();
            Calendar date = Calendar.getInstance();
            date.add(Calendar.YEAR, 1);
            apiKey.setEndDate(date.getTime());
            apiKey.setvCode(RandomStringUtils.randomAlphanumeric(40));
            if (filledUserForm.field("isAdmin").value() != null && user.getApiAccess().isEmpty()) {
                user.getApiAccess().add(apiKey);
            }

            if (user.getId() == null) {
                user.save();
            } else {
                if (filledUserForm.field("isAdmin").value() == null) {
                    for (ApiKey key : user.getApiAccess()) {
                        key.delete();
                    }
                }
                user.update();
            }

            return ok(result);
        }
    }

    public static Result settings() {
        userForm = Form.form(User.class);
        User user = User.find.byId(Long.valueOf(session().get("user")));

        return ok(views.html.User.User.settings.render(userForm, user.getApiAccess(), ""));
    }

    public static Result changePassword() {
        Form<User> filledUserForm = userForm.bindFromRequest();
        User user = User.find.byId(Long.valueOf(session().get("user")));
        filledUserForm.errors().remove("username");

        if (filledUserForm.hasErrors()) {
            // Return error if empty fields
            return ok(views.html.User.User.settings.render(filledUserForm, new ArrayList<ApiKey>(), ""));
        } else if (!request().body().asMultipartFormData().asFormUrlEncoded().containsKey("oldPassword")) {
            return ok(views.html.User.User.settings.render(filledUserForm, new ArrayList<ApiKey>(),
                    "<p class='error'>Old password is empty !</p>"));
        } else if (!Utils.getSaltedPassword(
                request().body().asMultipartFormData().asFormUrlEncoded().get("oldPassword")[0]).equals(
                user.getPassword())) {
            return ok(views.html.User.User.settings.render(filledUserForm, new ArrayList<ApiKey>(),
                    "<p class='error'>Old password is wrong !</p>"));
        } else {
            user.setPassword(Utils.getSaltedPassword(filledUserForm.field("password").value()));
            user.save();
        }

        return ok(views.html.User.User.settings.render(userForm, new ArrayList<ApiKey>(),
                "<p class='success'>Password changed !</p>"));
    }

    public static Result api() {
        return ok(views.html.User.User.api.render(session().get("keyId"), session().get("vCode")));
    }
}